package mylab.utils.common;

import com.google.common.base.Preconditions;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import cn.hutool.core.util.ArrayUtil;
import lombok.experimental.UtilityClass;

@UtilityClass
public class ByteUtil extends cn.hutool.core.util.ByteUtil {

    public static final Charset CHARSET = StandardCharsets.UTF_8;
    ;

    /**
     * byte 与 int 的相互转换
     */
    public byte intToByte(int x) {
        return (byte) x;
    }

    public short byteToShort(byte b) {
        return (short) byteToInt(b);
    }

    public int byteToInt(byte b) {
        // Java 总是把 byte 当做有符处理；我们可以通过将其和 0xFF 进行二进制与得到它的无符值
        return b & 0xFF;
    }

    public int bytesToUnsignedInt(byte[] bytes) {
        int ret = 0;
        int size = bytes.length;
        int beginPos = Math.min(size, 4);
        for (int i = beginPos - 1; i >= 0; --i) {
            ret = (ret << 8) | (bytes[i] & 0xff);
        }
        return ret;
    }

    public byte[] stringToBytes(String string) {
        return string.getBytes(CHARSET);
    }

    public String bufferToString(ByteBuffer buffer, int length) {
        byte[] value = new byte[length];
        buffer.get(value);
        return bytesToString(value, 0, length);
    }

    public String bytesToString(byte[] value) {
        return new String(value, CHARSET);
    }

    public String bytesToString(byte[] value, int startIndex, int length) {
        try {
            return new String(value, startIndex, Math.min(value.length, length), CHARSET).trim();
        } catch (Exception e) {
            return null;
        }
    }

    public static String bytes2HexString(byte[] bytes, int startIndex, int length) {
        Preconditions.checkNotNull(bytes);
        Preconditions.checkState(startIndex >= 0 && startIndex < bytes.length);
        Preconditions.checkState(length >= 0 && length <= bytes.length);

        if (startIndex + length > bytes.length) {
            length = bytes.length - startIndex;
        }

        byte[] res = new byte[length];
        System.arraycopy(bytes, startIndex, res, 0, length);
        return bytes2HexString(res);
    }

    public static String bytes2HexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex).append(" ");
        }
        return sb.toString();
    }

    public byte[] reverseBytes(byte[] bytes) {
        return ArrayUtil.reverse(bytes);
    }

    public ByteBuffer allocate(int capacity, ByteOrder byteOrder) {
        return ByteBuffer.allocate(capacity).order(byteOrder);
    }
}
